package com.markby.fscm.cryptogram.domain.standard0016;

import lombok.Data;
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;

import java.nio.ByteOrder;

import static com.markby.fscm.cryptogram.domain.standard0016.Constant0016.ECC_MAX_XCOORDINATE_BITS_LEN;
import static com.markby.fscm.cryptogram.domain.standard0016.Constant0016.ECC_MAX_YCOORDINATE_BITS_LEN;
import static com.markby.fscm.cryptogram.uitls.HexUtils.intToBytes;


/**
 * 0016-2023规范 ECC公钥数据结构
 * ULONG 为32位无符号整数
 * typedef struct Struct_ECCPUBLICKEYBLOB{
 * ULONG	BitLen;											// 模数的实际位长度(应是8的倍数) 256或者512
 * BYTE 	XCoordinate[ECC_MAX_XCOORDINATE_BITS_LEN/8];	// 曲线上点的X坐标(有限域上的整数 #define ECC_MAX_XCOORDINATE_BITS_LEN 512)
 * BYTE	YCoordinate[ECC_MAX_YCOORDINATE_BITS_LEN/8];	// 曲线上点的Y坐标(有限域上的整数 #define ECC_MAX_YCOORDINATE_BITS_LEN 512)
 * }ECCPUBLICKEYBLOB,*PECCPUBLICKEYBLOB;
 * ECC_MAX_XCOORDINATE_LEN为ECC算法X坐标的最大长度;
 * ECC_MAX_YCOORDINATE_LEN为ECC算法Y坐标的最大长度。
 */
@Data
public class ECCPUBLICKEYBLOB {

    private int BitLen;
    private byte[] XCoordinate;
    private byte[] YCoordinate;

    public ECCPUBLICKEYBLOB(int bitLen, byte[] xCoordinate, byte[] yCoordinate) {
        if (xCoordinate.length != ECC_MAX_XCOORDINATE_BITS_LEN / 8) {
            throw new IllegalArgumentException("Invalid XCoordinate length: " + xCoordinate.length);
        }
        if (yCoordinate.length != ECC_MAX_YCOORDINATE_BITS_LEN / 8) {
            throw new IllegalArgumentException("Invalid YCoordinate length: " + yCoordinate.length);
        }
        this.BitLen = bitLen;
        this.XCoordinate = xCoordinate;
        this.YCoordinate = yCoordinate;
    }

    public ECCPUBLICKEYBLOB(BCECPublicKey encPubKey, int BitLen) {
        byte[] XBytes = encPubKey.getW().getAffineX().toByteArray();
        byte[] YBytes = encPubKey.getW().getAffineY().toByteArray();

//        if (XBytes.length > ECC_MAX_XCOORDINATE_BITS_LEN / 8) {
//            throw new IllegalArgumentException("Invalid X length: " + XBytes.length);
//        }
//        if (YBytes.length > ECC_MAX_YCOORDINATE_BITS_LEN / 8) {
//            throw new IllegalArgumentException("Invalid Y length: " + YBytes.length);
//        }
        XCoordinate = new byte[ECC_MAX_XCOORDINATE_BITS_LEN / 8];
        YCoordinate = new byte[ECC_MAX_YCOORDINATE_BITS_LEN / 8];
        if (BitLen == 256) {
            int len = ECC_MAX_XCOORDINATE_BITS_LEN / 8 / 2;
            System.arraycopy(XBytes, XBytes.length - len, XCoordinate, XCoordinate.length - len, len);
            System.arraycopy(YBytes, YBytes.length - len, YCoordinate, YCoordinate.length - len, len);
        } else if (BitLen == 512) {
            int len = ECC_MAX_XCOORDINATE_BITS_LEN / 8;
            System.arraycopy(XBytes, XBytes.length - len, XCoordinate, XCoordinate.length - len, len);
            System.arraycopy(YBytes, YBytes.length - len, YCoordinate, YCoordinate.length - len, len);
        }

        this.BitLen = BitLen;
    }

    public byte[] getBytes() {
        byte[] bitLenBytes = intToBytes(BitLen, ByteOrder.LITTLE_ENDIAN);
        byte[] xCoordinateBytes = XCoordinate;
        byte[] yCoordinateBytes = YCoordinate;
        byte[] result = new byte[bitLenBytes.length + xCoordinateBytes.length + yCoordinateBytes.length];
        System.arraycopy(bitLenBytes, 0, result, 0, bitLenBytes.length);
        System.arraycopy(xCoordinateBytes, 0, result, bitLenBytes.length, xCoordinateBytes.length);
        System.arraycopy(yCoordinateBytes, 0, result, bitLenBytes.length + xCoordinateBytes.length, yCoordinateBytes.length);
        return result;
    }
}
